#include "aescrypto.h"
#include <QDebug>

AesCrypto::AesCrypto(QString key)
{
    QByteArray arrKey = key.toUtf8();
    qDebug() << "AES key: " << arrKey.data()
             << "AES KeyLen: " << arrKey.size();

    if (arrKey.size() == 16 || arrKey.size() == 24 || arrKey.size() == 32)
    {
        const unsigned char* aesKey = (const unsigned char*)arrKey.data();
        AES_set_encrypt_key(aesKey, arrKey.size() * 8, &m_encKey);
        AES_set_decrypt_key(aesKey, arrKey.size() * 8, &m_decKey);
        m_key = arrKey;
    }
}

AesCrypto::~AesCrypto()
{
}

QString AesCrypto::aesCBCEncrypt(QString text)
{
    return aesCrypto(text, AES_ENCRYPT);
}

QString AesCrypto::aesCBCDecrypt(QString encStr)
{
    return aesCrypto(encStr, AES_DECRYPT);
}

QString AesCrypto::aesCrypto(QString data, int crypto)
{
    QByteArray arrData;
    if(crypto == AES_ENCRYPT)
    {
        arrData = data.toUtf8();
    }
    else
    {
        arrData = QByteArray::fromBase64(data.toUtf8());
    }
    AES_KEY* key = crypto == AES_ENCRYPT ? &m_encKey : &m_decKey;

    unsigned char ivec[AES_BLOCK_SIZE];
    int length = arrData.size() + 1;	// +1 是添加\0的长度
    if (length % 16)
    {
        length = (length / 16 + 1) * 16;
    }
    char* out = new char[length];
    generateIvec(ivec);

    AES_cbc_encrypt((const unsigned char*)arrData.data(),
                    (unsigned char*)out, length, key, ivec, crypto);

    QByteArray retStr;
    if(crypto == AES_ENCRYPT)
    {
        retStr = QByteArray(out, length).toBase64();
    }
    else
    {
        retStr = QByteArray(out);
    }
    delete[]out;
    return QString(retStr);
}

void AesCrypto::generateIvec(unsigned char* ivec)
{
    for (int i = 0; i < AES_BLOCK_SIZE; ++i)
    {
        ivec[i] = m_key.at(AES_BLOCK_SIZE - i - 1);
    }
}

